﻿--[[
   @brief    bit operation utility 
   @author   hqzheng
   @version  1.0
   @date     2017-7-5
--]]

bit_operation_utility = {
    data32 = {};

    init = function ()
        for i = 1, 32 do
            bit_operation_utility.data32[i] = 2^(32-i);
        end
    end;

    -- 十进制转二进制
    d2b = function (arg)
        local   tr = {};
        for i = 1, 32 do
            if arg >= bit_operation_utility.data32[i] then
                tr[i] = 1;
                arg = arg - bit_operation_utility.data32[i]
            else
            tr[i] = 0;
            end
        end
        return  tr;
    end;

    -- 二进制转十进制
    b2d = function (arg)
        local   nr = 0;
        for i = 1, 32 do
            if arg[i] == 1 then
                nr = nr + 2^(32 - i);
            end
        end
        return  nr;
    end;

    -- xor
    xor_op = function (a, b)
        local   op1 = bit_operation_utility.d2b(a);
        local   op2 = bit_operation_utility.d2b(b);
        local   r = {};

        for i = 1, 32 do
            if op1[i] == op2[i] then
                r[i] = 0;
            else
                r[i] = 1;
            end
        end
        return  bit_operation_utility.b2d(r);
    end;

    -- and
    and_op = function (a, b)
        local   op1 = bit_operation_utility.d2b(a);
        local   op2 = bit_operation_utility.d2b(b);
        local   r = {};
    
        for i = 1, 32 do
            if op1[i] == 1 and op2[i] == 1 then
                r[i] = 1;
            else
                r[i] = 0;
            end
        end
        return  bit_operation_utility.b2d(r)
    end;

    -- or
    or_op = function (a, b)
        local   op1 = bit_operation_utility.d2b(a);
        local   op2 = bit_operation_utility.d2b(b);
        local   r = {};
    
        for i = 1, 32 do
            if  op1[i] == 1 or  op2[i] == 1  then
                r[i] = 1;
            else
                r[i] = 0;
            end
        end
        return  bit_operation_utility.b2d(r);
    end;

    -- not
    not_op = function (arg)
        local   op1 = bit_operation_utility.d2b(arg);
        local   r = {};

        for i = 1, 32 do
            if  op1[i] == 1 then
                r[i] = 0;
            else
                r[i] = 1;
            end
        end
        return  bit_operation_utility.b2d(r)
    end;

    -- rshift
    rshift = function (a, n)
        local   op1 = bit_operation_utility.d2b(a);
        local   r = bit_operation_utility.d2b(0);
    
        if n < 32 and n > 0 then
            for i = 1, n do
                for i = 31, 1, -1 do
                    op1[i+1] = op1[i];
                end
                op1[1] = 0;
            end
        r = op1;
        end
        return  bit_operation_utility.b2d(r)
    end;

    -- lshift
    lshift = function (a, n)
        local   op1 = bit_operation_utility.d2b(a);
        local   r = bit_operation_utility.d2b(0);
    
        if n < 32 and n > 0 then
            for i = 1, n do
                for i = 1, 31 do
                    op1[i] = op1[i+1];
                end
                op1[32] = 0;
            end
        r = op1;
        end
        return  bit_operation_utility.b2d(r);
    end;
};

bit_operation_utility.init();